package myJs.tool

import myJs.myPkg.jquery._
import scalatags.Text.all._
import shared.Pojo.{SnpReadsData, StrReadsData}

import scala.scalajs.js
import scala.scalajs.js.JSON
import myJs.Implicits._
import myJs.tool.Pojo.GenotypeData

import scala.scalajs.js.JSConverters._
import myJs.Utils._
import myJs.myPkg._
import org.scalajs.dom.ext.Ajax
import myJs.myPkg.bootstrap.Bootstrap.default._
import scalatags.Text.all

import scala.collection.immutable.SeqMap
import scala.concurrent.ExecutionContext.Implicits.global
import scala.scalajs.js.Dynamic.{global => g}

/**
 * Created by yz on 21/6/2021
 */
trait ProjectTool {

  val exportDatModalId = s"exportDatModal"
  val exportAllDatModalId = "exportAllDatModal"

  def getBgColor(key: (String, String), levelMap: Map[(String, String), String]) = {
    val isHighLevel = levelMap.getOrElse(key, "").split(";").contains("h")
    val bgColor = if (isHighLevel) "#FABD82" else "white"
    bgColor
  }

  def initStrTable = {
    val map = SeqMap(
      "genotype" -> "Allele Name",
      "typedAllele" -> "Typed Allele",
      "reads" -> "Reads",
      "repeatSeq" -> "Repeat Sequence",
      "snp" -> "SNP"
    )
    val columnNames = map.keys.toJSArray
    val columns = columnNames.map { columnName =>
      val title = map.getOrElse(columnName, columnName)
      ColumnOptions.field(columnName).title(title).sortable(true)
    }
    val options = TableOptions.columns(columns)
    $(s"#locusModal #detailTable").bootstrapTable(options)
  }

  def tbFmt(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[js.Any]) => columnName match {
    case "siteName" => {
      a(title := "详情", href := "javascript:;",
        onclick := s"SampleDetail.strDetailShow('${row("rawSeqs")}','${v}')", cursor.pointer,
        v.toString
      ).render
    }
    case _ => v
  }

  def snpTbFmt(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[js.Any]) => columnName match {
    case "siteName" => {
      a(title := "详情", href := "javascript:;",
        onclick := s"SampleDetail.snpDetailShow('${row("rawSeqs")}','${v}')", cursor.pointer,
        v.toString
      ).render
    }
    case "genoType" => {
      val colStr = getGenotypeCol(v.toString)
      span(color := colStr, v.toString)
    }
    case _ => v
  }

  def rowStyle: js.Function = (row: js.Dictionary[js.Any], index: Int) => {
    val isHighLevel = row("level") == "h"
    val bgColor = if (isHighLevel) "#FABD82" else "white"
    val cls = if (isHighLevel) "myHighTr" else ""
    js.Dictionary(
      "css" -> js.Dictionary("background" -> bgColor),
      "classes" -> s"${cls}"
    )
  }

  def initOuterStrTable(tableJq: JQuery) = {
    val map = SeqMap(
      "siteName" -> "位点名",
      "genoType" -> "分型数值",
      "repeatSeq" -> "重复序列",
      "reads" -> "深度",
      "snp" -> "SNP"
    )
    val columnNames = map.keys.toJSArray
    val columns = columnNames.map { columnName =>
      val title = map.getOrElse(columnName, columnName)
      val fmt = tbFmt(columnName)
      ColumnOptions.field(columnName).title(title).sortable(true).formatter(fmt)
    }
    val pageList = js.Array(10, 25, 50, 100)
    val options = TableOptions.columns(columns).pagination(true).pageList(pageList).search(true).rowStyle(rowStyle)
    tableJq.bootstrapTable(options)
  }

  def initOuterSnpTable(tableJq: JQuery) = {
    val map = SeqMap(
      "siteName" -> "位点名",
      "genoType" -> "分型数值",
      "reads" -> "深度",
    )
    val columnNames = map.keys.toJSArray
    val columns = columnNames.map { columnName =>
      val title = map.getOrElse(columnName, columnName)
      val fmt = snpTbFmt(columnName)
      ColumnOptions.field(columnName).title(title).sortable(true).formatter(fmt)
    }
    val pageList = js.Array(10, 25, 50, 100)
    val options = TableOptions.columns(columns).pagination(true).pageList(pageList).search(true).rowStyle(rowStyle)
    tableJq.bootstrapTable(options)
  }

  def getGenotypeCol(genoType: String) = {
    genoType match {
      case "A" => "#204E8A"
      case "T" => "#3B3E42"
      case "C" => "#7D8246"
      case "G" => "#843D3D"
      case _ => "#333"
    }
  }

  def fillReadsData(sample: js.Dictionary[js.Any], datas: List[StrReadsData], jq: JQuery, widthI: Int = 150) = {
    val array = datas.map { data =>
      val key = data.locus
      val dictOp = sample.get(key).map(_.toJDJAn)
      val rawSeqsOp = dictOp.map { dict =>
        dict("rawSeqs").toJArJDS
      }
      val rawSeqMapOp = rawSeqsOp.map { rawSeqs =>
        rawSeqs.filter { dt =>
          dt("typedAllele").equalsIgnoreCase("Yes")
        }.map { dt =>
          ((dt("genotype"),dt("snp")) -> dt)
        }.toMap
      }
      val curRawSeqOp = rawSeqMapOp.map { rawSeqMap =>
        rawSeqMap((data.genotype,data.snp))
      }
      val snp = curRawSeqOp.map { curRawSeq =>
        curRawSeq.getOrElse("snp", "")
      }.getOrElse("")
      val repeatSeq = curRawSeqOp.map { curRawSeq =>
        curRawSeq("repeatSeq")
      }.getOrElse("")
      val rawSeqs = rawSeqsOp.map { rawSeqs =>
        JSON.stringify(rawSeqs)
      }.getOrElse("")
      js.Dictionary("siteName" -> data.locus, "genoType" -> data.genotype, "repeatSeq" -> s"${repeatSeq}",
        "reads" -> data.reads, "snp" -> s"${snp}", "rawSeqs" -> rawSeqs, "level" -> data.level)
    }.toJSArray
    jq.bootstrapTable("load", array)
  }

  def fillSnpReadsData(sample: JDJAn, datas: List[SnpReadsData], jq: JQuery) = {
    val array = datas.map { data =>
      val key = data.locus
      val dict = sample(key).toJDJAn
      val rawSeqs = dict("rawSeqs").toJArJDS
      val rawSeqMap = rawSeqs.map { dt =>
        (dt("genotype") -> dt)
      }.toMap
      val curRawSeq = rawSeqMap(data.genotype)
      js.Dictionary("siteName" -> data.locus, "genoType" -> data.genotype,
        "reads" -> data.reads,"rawSeqs" -> JSON.stringify(rawSeqs), "level" -> data.level)
    }.toJSArray
    jq.bootstrapTable("load", array)
  }

  def getExportDatMap(modalId: String): Map[String, js.Any] = {
    val kitName = $(s"#${modalId} :input[name='kitName']:checked").`val`().toString
    val isSplit = $(s"#${modalId}").findInputByName("isSplit").isChecked
    val hasGroup = $(s"#${modalId}").findInputByName("hasGroup").isChecked
    val sampleNum = $(s"#${modalId}").findInputByName("sampleNum").myVal
    Map("kitName" -> kitName, "isSplit" -> isSplit, "hasGroup" -> hasGroup, "sampleNum" -> sampleNum)
  }

}
